﻿//-----------------------------------------------------------------------
// <copyright file="Folders.cs" company="FastNET Services">
//     Copyright (c) 2008-2009. All Rights Reserved.
// </copyright>
// <license>
//     GPLv2
// </license>
// <warranty>
//     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
//     BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
//     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
//     DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//     OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
// </warranty>
//-----------------------------------------------------------------------
#region Usings
using System;
using System.Runtime.InteropServices;
using System.Text;
#endregion

namespace FastNET.CleanAct.Client.Win32.Unmanaged
{
    /// <summary>
    /// Unmanaged resources for retrieving and maintaining folder locations in windows
    /// </summary>
    internal class Folders
    {
        /// <summary>
        /// One or more arguments are not valid
        /// </summary>
        public const uint E_INVALIDARG = 0x80070057;

        /// <summary>
        /// Operation successful
        /// </summary>
        public const uint S_OK = 0x00000000;

        #region Vista and Later

        /// <summary>
        /// Retrieves the full path of a known folder identified by the folder's KNOWNFOLDERID.
        /// </summary>
        /// <param name="folderID">A reference to the KNOWNFOLDERID that identifies the folder.</param>
        /// <param name="flags">Flags that specify special retrieval options. This value can be 0; otherwise, one or more of the KNOWN_FOLDER_FLAG values.</param>
        /// <param name="userToken">
        /// An access token that represents a particular user. If this parameter is NULL, which is the most common usage, the function
        /// requests the known folder for the current user. 
        /// 
        /// Request a specific user's folder by passing the hToken of that user. This is typically done in the context of a service that
        /// has sufficient privileges to retrieve the token of a given user. In addition to passing the user's hToken, the registry hive
        /// of that specific user must be mounted.
        /// 
        /// Assigning the hToken parameter a value of -1 indicates the Default User. This allows clients of SHGetKnownFolderPath to find
        /// folder locations (such as the Desktop folder) for the Default User. The Default User user profile is duplicated when any new
        /// user account is created, and includes special folders such as Documents and Desktop. Any items added to the Default User folder
        /// also appear in any new user account. Note that access to the Default User folders requires administrator privileges.
        /// </param>
        /// <param name="path"> Path to the folder requested</param>
        /// <returns>Returns S_OK if successful, or an error value otherwise</returns>
        [DllImport("shell32.dll")]
        public static extern uint SHGetKnownFolderPath([MarshalAs(UnmanagedType.LPStruct)] Guid folderID, KnownFolderFlags flags, IntPtr userToken, [Out] StringBuilder path);

        /// <summary>
        /// Specify special retrieval options for known folders. These values supersede CSIDL values, which have parallel meanings.
        /// </summary>
        [Flags]
        public enum KnownFolderFlags : uint
        {
            /// <summary>
            /// No flags are applied
            /// </summary>
            None = 0,

            /// <summary>
            /// Forces the creation of the specified folder if that folder does not already exist. The security provisions
            /// predefined for that folder are applied. If the folder does not exist and cannot be created, the function
            /// returns a failure code and no path is returned. This flag cannot be used with SHSetKnownFolderPath and
            /// IKnownFolder::SetPath.
            /// </summary>
            Create = 0x00008000,

            /// <summary>
            /// Do not verify the folder's existence before attempting to retrieve the path or IDList. If this flag is not
            /// set, an attempt is made to verify that the folder is truly present at the path. If that verification fails
            /// due to the folder being absent or inaccessible, the function returns a failure code and no path is returned. 
            ///
            /// If the folder is located on a network, the function might take a longer time to execute. Setting this flag
            /// can reduce that lag time.
            /// </summary>
            DontVerify = 0x00004000,

            /// <summary>
            /// Stores the full path in the registry without using environment strings. If this flag is not set, portions
            /// of the path may be represented by environment strings such as %USERPROFILE%. This flag can only be used
            /// with SHSetKnownFolderPath and IKnownFolder::SetPath.
            /// </summary>
            DontUnexpand = 0x00002000,

            /// <summary>
            /// Gets the true system path for the folder, free of any aliased placeholders such as %USERPROFILE%, returned
            /// by SHGetKnownFolderIDList and IKnownFolder::GetIDList. This flag has no effect on paths returned by
            /// SHGetKnownFolderPath and IKnownFolder::GetPath. By default, known folder retrieval functions and methods
            /// return the aliased path if an alias exists.
            /// </summary>
            NoAlias = 0x00001000,

            /// <summary>
            /// Initializes the folder using its Desktop.ini settings. If the folder cannot be initialized, the function
            /// returns a failure code and no path is returned. This flag should always be combined with KF_FLAG_CREATE. 
            ///
            /// If the folder is located on a network, the function might take a longer time to execute.
            /// </summary>
            Initialize = 0x00000800,

            /// <summary>
            /// Gets the default path for a known folder. If this flag is not set, the function retrieves the current
            /// and possibly redirectedpath of the folder. The execution of this flag includes a verification of the 
            /// folder's existence unless KF_FLAG_DONT_VERIFY is set.
            /// </summary>
            DefaultPath = 0x00000400,

            /// <summary>
            /// Gets the folder's default path independent of the current location of its parent. KF_FLAG_DEFAULT_PATH must also be set.
            /// </summary>
            NotParentRelative = 0x00000200,

            /// <summary>
            /// Build a simple pointer to an item identifier list (PIDL).
            /// </summary>
            SimpleIDList = 0x00000100,

            /// <summary>
            /// Windows 7 and later. Return only aliased PIDLs. Do not use the file system path.
            /// </summary>
            AliasOnly = 0x80000000
        }

        #endregion

        #region XP and earlier

        /// <summary>
        /// Flags that specify the path to be returned
        /// </summary>
        [Flags]
        public enum SpecialFolderFlags : uint
        {
            /// <summary>
            /// Retrieve the folder's current path.
            /// </summary>
            TypeCurrent = 0,

            /// <summary>
            /// Retreive the folder's default path.
            /// </summary>
            TypeDefault = 1
        }

        /// <summary>
        /// Deprecated. Gets the path of a folder identified by a CSIDL value. Used only for older clients
        /// </summary>
        /// <param name="hwndOwner">Reserved. Use IntPtr.Zero</param>
        /// <param name="folder">SpecialFolderType with the folder being requested</param>
        /// <param name="userToken">
        /// An access token that represents a particular user. If this parameter is NULL, which is the most common usage, the function
        /// requests the known folder for the current user. 
        /// 
        /// Request a specific user's folder by passing the hToken of that user. This is typically done in the context of a service that
        /// has sufficient privileges to retrieve the token of a given user. In addition to passing the user's hToken, the registry hive
        /// of that specific user must be mounted.
        /// 
        /// Assigning the hToken parameter a value of -1 indicates the Default User. This allows clients of SHGetKnownFolderPath to find
        /// folder locations (such as the Desktop folder) for the Default User. The Default User user profile is duplicated when any new
        /// user account is created, and includes special folders such as Documents and Desktop. Any items added to the Default User folder
        /// also appear in any new user account. Note that access to the Default User folders requires administrator privileges.
        /// </param>
        /// <param name="dwFlags">
        /// Flags that specify the path to be returned. This value is used in cases where the folder associated with a KNOWNFOLDERID
        /// (or CSIDL) can be moved, renamed, redirected, or roamed across languages by a user or administrator. The known folder system
        /// that underlies SHGetFolderPath allows users or administrators to redirect a known folder to a location that suits their needs.
        /// </param>
        /// <param name="path">Path to the folder requested</param>
        /// <returns>Returns S_OK if successful, or an error value otherwise</returns>
        [DllImport("shell32.dll")]
        public static extern uint SHGetFolderPath(IntPtr hwndOwner, [MarshalAs(UnmanagedType.I4)] SpecialFolderType folder, IntPtr userToken, [MarshalAs(UnmanagedType.U4)] SpecialFolderFlags dwFlags, [Out] StringBuilder path);

        /// <summary>
        /// CSIDL (constant special item ID list) values provide a unique system-independent way to identify special folders
        /// used frequently by applications, but which may not have the same name or location on any given system. For example,
        /// the system folder may be "C:\Windows" on one system and "C:\Winnt" on another.
        /// </summary>
        public enum SpecialFolderType
        {
            /// <summary>
            /// Version 5.0. The file system directory that is used to store administrative tools for an individual user. 
            /// The Microsoft Management Console (MMC) will save customized consoles to this directory, and it will roam with the user.
            /// </summary>
            AdministrativeTools = 0x0030,

            /// <summary>
            /// The file system directory that corresponds to the user's nonlocalized Startup program group.
            /// </summary>
            AltStartup = 0x001d,

            /// <summary>
            /// Version 4.71. The file system directory that serves as a common repository for application-specific data. 
            /// A typical path is C:\Documents and Settings\username\Application Data. This CSIDL is supported by the
            /// redistributable Shfolder.dll for systems that do not have the Microsoft Internet Explorer 4.0 integrated Shell installed.
            /// </summary>
            ApplicationData = 0x001a,

            /// <summary>
            /// The virtual folder containing the objects in the user's Recycle Bin. 
            /// </summary>
            RecycleBin = 0x000a,

            /// <summary>
            /// The file system directory acting as a staging area for files waiting to be written to CD.
            /// A typical path is C:\Documents and Settings\username\Local Settings\Application Data\Microsoft\CD Burning. 
            /// </summary>
            CDBurning = 0x003b,

            /// <summary>
            /// Version 5.0. The file system directory containing administrative tools for all users of the computer.
            /// </summary>
            CommonAdministrativeTools = 0x002f,

            /// <summary>
            /// The file system directory that corresponds to the nonlocalized Startup program group for all users.
            /// Valid only for Microsoft Windows NT systems. 
            /// </summary>
            CommonAltStartup = 0x001e,

            /// <summary>
            /// Version 5.0. The file system directory containing application data for all users. A typical path is 
            /// C:\Documents and Settings\All Users\Application Data.
            /// </summary>
            CommonAppData = 0x0023,

            /// <summary>
            /// The file system directory that contains files and folders that appear on the desktop for all users.
            /// A typical path is C:\Documents and Settings\All Users\Desktop. Valid only for Windows NT systems.
            /// </summary>
            CommonDesktop = 0x0019,

            /// <summary>
            /// The file system directory that contains documents that are common to all users. A typical paths is 
            /// C:\Documents and Settings\All Users\Documents. Valid for Windows NT systems and Microsoft Windows 95 and 
            /// Windows 98 systems with Shfolder.dll installed.
            /// </summary>
            CommonDocuments = 0x002e,

            /// <summary>
            /// The file system directory that serves as a common repository for favorite items common to all users.
            /// Valid only for Windows NT systems. 
            /// </summary>
            CommonFavorites = 0x001f,

            /// <summary>
            /// The file system directory that serves as a repository for music files common to all users.
            /// A typical path is C:\Documents and Settings\All Users\Documents\My Music. 
            /// </summary>
            CommonMusic = 0x0035,

            /// <summary>
            /// This value is recognized in Windows Vista for backward compatibility, but the folder itself is no longer used.
            /// </summary>
            CommonOemLinks = 0x003a,

            /// <summary>
            /// The file system directory that serves as a repository for image files common to all users. 
            /// A typical path is C:\Documents and Settings\All Users\Documents\My Pictures. 
            /// </summary>
            CommonPictures = 0x0036,

            /// <summary>
            /// The file system directory that contains the directories for the common program groups that
            /// appear on the Start menu for all users. A typical path is C:\Documents and Settings\All 
            /// Users\Start Menu\Programs. Valid only for Windows NT systems. 
            /// </summary>
            CommonPrograms = 0X0017,

            /// <summary>
            /// The file system directory that contains the programs and folders that appear on the Start menu
            /// for all users. A typical path is C:\Documents and Settings\All Users\Start Menu. Valid only for
            /// Windows NT systems.
            /// </summary>
            CommonStartMenu = 0x0016,

            /// <summary>
            /// The file system directory that contains the programs that appear in the Startup folder for all 
            /// users. A typical path is C:\Documents and Settings\All Users\Start Menu\Programs\Startup. Valid
            /// only for Windows NT systems. 
            /// </summary>
            CommonStartup = 0x0018,

            /// <summary>
            /// The file system directory that contains the templates that are available to all users. A typical 
            /// path is C:\Documents and Settings\All Users\Templates. Valid only for Windows NT systems. 
            /// </summary>
            CommonTemplates = 0x002d,

            /// <summary>
            /// The file system directory that serves as a repository for video files common to all users. A typical
            /// path is C:\Documents and Settings\All Users\Documents\My Videos. 
            /// </summary>
            CommonVideo = 0x0037,

            /// <summary>
            /// The folder that represents other computers in your workgroup.
            /// </summary>
            ComputersNearMe = 0x003d,

            /// <summary>
            /// The virtual folder that represents Network Connections, that contains network and dial-up connections.
            /// </summary>
            Connections = 0x0031,

            /// <summary>
            /// The virtual folder containing icons for the Control Panel applications.
            /// </summary>
            Controls = 0x0003,

            /// <summary>
            /// The file system directory that serves as a common repository for Internet cookies. A typical path is 
            /// C:\Documents and Settings\username\Cookies.
            /// </summary>
            Cookies = 0x0021,

            /// <summary>
            /// The virtual folder representing the Windows desktop, the root of the namespace.
            /// </summary>
            Desktop = 0x0000,

            /// <summary>
            /// The file system directory used to physically store file objects on the desktop (not to be confused with
            /// the desktop folder itself). A typical path is C:\Documents and Settings\username\Desktop. 
            /// </summary>
            DesktopDirectory = 0x0010,

            /// <summary>
            /// The virtual folder representing My Computer, containing everything on the
            /// local computer: storage devices, printers, and Control Panel. The folder may
            /// also contain mapped network drives. 
            /// </summary>
            Drives = 0x0011,

            /// <summary>
            /// The file system directory that serves as a common repository for the user's
            /// favorite items. A typical path is C:\Documents and Settings\username\Favorites. 
            /// </summary>
            Favorites = 0x0006,

            /// <summary>
            /// A virtual folder containing fonts. A typical path is C:\Windows\Fonts.
            /// </summary>
            Fonts = 0x0014,

            /// <summary>
            /// The file system directory that serves as a common repository for Internet history items.
            /// </summary>
            History = 0x0022,

            /// <summary>
            /// A virtual folder representing the Internet.
            /// </summary>
            Internet = 0x0001,

            /// <summary>
            /// Version 4.72. The file system directory that serves as a common repository for temporary Internet files. A typical 
            /// path is C:\Documents and Settings\username\Local Settings\Temporary Internet Files.
            /// </summary>
            InternetCache = 0x0020,

            /// <summary>
            /// Version 5.0. The file system directory that serves as a data repository for local (nonroaming) applications. 
            /// A typical path is C:\Documents and Settings\username\Local Settings\Application Data.
            /// </summary>
            LocalApplicationData = 0x001c,

            /// <summary>
            /// The virtual folder representing the My Documents desktop item.
            /// </summary>
            MyDocuments = 0x000c,

            /// <summary>
            /// The file system directory that serves as a common repository for music files. A typical 
            /// path is C:\Documents and Settings\User\My Documents\My Music. 
            /// </summary>
            MyMusic = 0x000d,

            /// <summary>
            /// Version 5.0. The file system directory that serves as a common repository for image files. A typical path is 
            /// C:\Documents and Settings\username\My Documents\My Pictures.
            /// </summary>
            MyPictures = 0x0027,

            /// <summary>
            /// The file system directory that serves as a common repository for video files. A typical 
            /// path is C:\Documents and Settings\username\My Documents\My Videos. 
            /// </summary>
            MyVideo = 0x000e,

            /// <summary>
            /// A file system directory containing the link objects that may exist in the My Network Places
            /// virtual folder. It is not the same as CSIDL_NETWORK, which represents the network namespace
            /// root. A typical path is C:\Documents and Settings\username\NetHood. 
            /// </summary>
            NetHood = 0x0013,

            /// <summary>
            /// A virtual folder representing Network Neighborhood, the root of the network namespace hierarchy. 
            /// </summary>
            Network = 0x0012,

            /// <summary>
            /// Version 6.0. The virtual folder representing the My Documents desktop item. This is equivalent to CSIDL_MYDOCUMENTS. 
            /// Previous to Version 6.0. The file system directory used to physically store a user's common repository of documents. 
            /// A typical path is C:\Documents and Settings\username\My Documents. This should be distinguished from the virtual My
            /// Documents folder in the namespace. To access that virtual folder, use SHGetFolderLocation, which returns the ITEMIDLIST
            /// for the virtual location, or refer to the technique described in Managing the File System.
            /// </summary>
            Personal = 0x0005,

            /// <summary>
            /// The virtual folder containing installed printers. 
            /// </summary>
            Printers = 0x0004,

            /// <summary>
            /// The file system directory that contains the link objects that can exist in the
            /// Printers virtual folder. A typical path is C:\Documents and Settings\username\PrintHood. 
            /// </summary>
            PrintHood = 0x001b,

            /// <summary>
            /// The user's profile folder. A typical path is C:\Documents and Settings\username. Applications
            /// should not create files or folders at this level; they should put their data under the locations
            /// referred to by CSIDL_APPDATA or CSIDL_LOCAL_APPDATA.
            /// </summary>
            Profile = 0x0028,

            /// <summary>
            /// Version 5.0. The Program Files folder. A typical path is C:\Program Files.
            /// </summary>
            ProgramFiles = 0x0026,

            /// <summary>
            /// Version 5.0. A folder for components that are shared across applications. A typical path is C:\Program Files\Common. 
            /// Valid only for Windows NT, Windows 2000, and Windows XP systems. Not valid for Windows Millennium Edition (Windows Me).
            /// </summary>
            CommonProgramFiles = 0x002b,

            /// <summary>
            /// The 32Bit representation of the CommonProgramFiles
            /// </summary>
            CommonProgramFilesX86 = 0x002c,

            /// <summary>
            /// The 32Bit representation of the ProgramFiles
            /// </summary>
            ProgramFilesX86 = 0x002a,

            /// <summary>
            /// The file system directory that contains the user's program groups (which are themselves file system directories). A
            /// typical path is C:\Documents and Settings\username\Start Menu\Programs. 
            /// </summary>
            Programs = 0x0002,

            /// <summary>
            /// The file system directory that contains shortcuts to the user's most recently used documents.
            /// A typical path is C:\Documents and Settings\username\My Recent Documents. To create a shortcut
            /// in this folder, use SHAddToRecentDocs. In addition to creating the shortcut, this function
            /// updates the Shell's list of recent documents and adds the shortcut to the My Recent Documents
            /// submenu of the Start menu. 
            /// </summary>
            Recent = 0x0008,

            /// <summary>
            /// Windows Vista. The file system directory that contains resource data. A typical path is C:\Windows\Resources.
            /// </summary>
            Resources = 0x0038,

            /// <summary>
            /// Localized version of the Resources Directory
            /// </summary>
            LocalizedResources = 0x0039,

            /// <summary>
            /// The file system directory that contains Send To menu items. A typical path is C:\Documents and Settings\username\SendTo. 
            /// </summary>
            SendTo = 0x0009,

            /// <summary>
            /// The file system directory containing Start menu items. A typical path is C:\Documents and Settings\username\Start Menu. 
            /// </summary>
            StartMenu = 0x000b,

            /// <summary>
            /// The file system directory that corresponds to the user's Startup program group. The system starts these
            /// programs whenever any user logs onto Windows NT or starts Windows 95. A typical path is C:\Documents and
            /// Settings\username\Start Menu\Programs\Startup.
            /// </summary>
            Startup = 0x0007,

            /// <summary>
            /// Version 5.0. The Windows System folder. A typical path is C:\Windows\System32.
            /// </summary>
            System = 0x0025,

            /// <summary>
            /// The 32Bit representation of the Windows System folder
            /// </summary>
            SystemX86 = 0x0029,

            /// <summary>
            /// The file system directory that serves as a common repository for document templates. A typical path is
            /// C:\Documents and Settings\username\Templates.
            /// </summary>
            Templates = 0x0015,

            /// <summary>
            /// Version 5.0. The Windows directory or SYSROOT. This corresponds to the %windir% or %SYSTEMROOT% environment 
            /// variables. A typical path is C:\Windows.
            /// </summary>
            Windows = 0x0024
        }

        #endregion
    }
}